package com.yenlien.traceyun.produce.service;

import com.yenlien.traceyun.business.dao.MaterialManagementDao;
import com.yenlien.traceyun.business.entity.MaterialManagement;
import com.yenlien.traceyun.business.service.rest.usercenter.FileRestService;
import com.yenlien.traceyun.produce.dao.ProcessSpecificationDao;
import com.yenlien.traceyun.produce.dao.ProcessTechnologysDao;
import com.yenlien.traceyun.produce.entity.ProcessSpecification;
import com.yenlien.traceyun.produce.entity.ProcessTechnologys;
import com.yenlien.traceyun.webase.exception.BusinessException;
import org.apache.commons.lang3.StringUtils;
import org.apache.poi.hssf.usermodel.*;
import org.apache.poi.poifs.filesystem.POIFSFileSystem;
import org.apache.poi.ss.usermodel.DataValidation;
import org.apache.poi.ss.usermodel.DataValidationConstraint;
import org.apache.poi.ss.usermodel.DataValidationHelper;
import org.apache.poi.ss.util.CellRangeAddressList;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.web.multipart.MultipartFile;

import javax.persistence.criteria.*;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 工艺工序
 */

@Service
public class TechnologysService {

    @Autowired
    private FileRestService fileRestService;

    @Autowired
    private ProcessTechnologysDao processTechnologyDao;

    @Autowired
    private ProcessSpecificationDao processSpecificationDao;

    @Autowired
    private MaterialManagementDao materialManagementDao;

    /**
     * 新增工艺工序
     *
     * @param processTechnology specification
     * @param files
     */
    @Transactional
    public void save(ProcessTechnologys processTechnology, List<ProcessSpecification> specification, List<MultipartFile> files) {
        if(!CollectionUtils.isEmpty(files)){
            String name = files.get(0).getOriginalFilename();
            processTechnology.setStandardImg(name);
            try {
                fileRestService.upload(null, processTechnology, files);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        String materialName = processTechnology.getMaterialName();
        List<MaterialManagement> byMaterialName = materialManagementDao.findByMaterialName(materialName);
        if (byMaterialName.size() == 0) {
            throw new BusinessException("没有该物料");
        }
        String id = byMaterialName.get(0).getId();
        processTechnology.setMaterialId(id);
        ProcessTechnologys save = processTechnologyDao.save(processTechnology);
        String technologyId = save.getId();
        for (int i = 0; i < specification.size(); i++) {
            specification.get(i).setTechnologyId(technologyId);
        }
        processSpecificationDao.saveAll(specification);
    }


    @Transactional
    public void save2(ProcessTechnologys processTechnology, List<ProcessSpecification> specification) {
        String materialName = processTechnology.getMaterialName();
        List<MaterialManagement> byMaterialName = materialManagementDao.findByMaterialName(materialName);
        if (byMaterialName.size() == 0) {
            throw new BusinessException("没有该物料");
        }
        String id = byMaterialName.get(0).getId();
        processTechnology.setMaterialId(id);
        ProcessTechnologys save = processTechnologyDao.save(processTechnology);
        String technologyId = save.getId();
        for (int i = 0; i < specification.size(); i++) {
            specification.get(i).setTechnologyId(technologyId);
        }
        processSpecificationDao.saveAll(specification);
    }

    /**
     * 查询工艺工序
     *
     * @param page
     * @return
     */
    public Page<ProcessTechnologys> select(Integer page, String companyId) {
        PageRequest pageRequest = PageRequest.of(page, 10, Sort.by(Sort.Direction.DESC, "createtime"));
//        Page<ProcessTechnologys> all = processTechnologyDao.findAll(pageRequest);
        return processTechnologyDao.findByCompanyId(companyId, pageRequest);
    }

    /**
     * * 搜索栏
     *
     * @param processName
     * @return
     */
    public Object search(String processName) {
        return processTechnologyDao.findByProcessNameLike(processName);
    }


    /**
     * 根据id查询工艺工序
     *
     * @param id
     * @return
     */
    public Object selectId(String id) {
        ProcessTechnologys byId = processTechnologyDao.findById(id);
        List<ProcessSpecification> byProcessPlanId = processSpecificationDao.findByTechnologyId(id);
        byId.setSpecification(byProcessPlanId);
        return byId;
    }

    /**
     * 根据id修改
     *
     * @param processTechnology,specification
     * @return
     */
    @Transactional
    public void update(ProcessTechnologys processTechnology, List<MultipartFile> files) {

        String id = processTechnology.getId();
        //processPlanDao.deleteById(id);
        if (!files.isEmpty()) {
            String name = files.get(0).getOriginalFilename();
            processTechnology.setStandardImg(name);
            try {
                fileRestService.upload(processTechnologyDao.findById(id), processTechnology, files);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        List<ProcessSpecification> specification = processTechnology.getSpecification();
        processSpecificationDao.deleteByTechnologyId(id);
        processTechnologyDao.save(processTechnology);
        if (specification != null && specification.size() > 0) {
            for (ProcessSpecification processSpecification : specification) {
                //todo
                processSpecification.setTechnologyId(id);
            }
            processSpecificationDao.saveAll(specification);
        } else {
            throw new BusinessException("500", "修改失败");
        }
    }


    public List<ProcessTechnologys> findByListNoPage(final ProcessTechnologys processTechnologys) {
        return processTechnologyDao.findAll((Root<ProcessTechnologys> root, CriteriaQuery<?> query, CriteriaBuilder cb) -> {
            Path<String> materialName = root.get("materialName");
            Path<String> processName = root.get("processName");
            Path<String> materialCode = root.get("materialCode");
            //构造查询条件
            List<Predicate> list = new ArrayList<Predicate>();
            list.add(cb.equal(root.get("companyId"), processTechnologys.getCompanyId()));
            if (StringUtils.isNotBlank(processTechnologys.getProcessName())) {
                list.add(cb.equal(processName, processTechnologys.getProcessName()));
            }
            if (StringUtils.isNotBlank(processTechnologys.getMaterialName())) {
                list.add(cb.equal(materialName, processTechnologys.getMaterialName()));
            }
            if (StringUtils.isNotBlank(processTechnologys.getMaterialCode())) {
                list.add(cb.equal(materialCode, processTechnologys.getMaterialCode()));
            }
            Predicate[] predicate = new Predicate[list.size()];
            return cb.and(list.toArray(predicate));
        });
    }

    /**
     * 根据id删除生产信息
     *
     * @param processTechnologyId
     */
    @Transactional
    public void delete(String processTechnologyId) {
        processTechnologyDao.deleteById(processTechnologyId);
        fileRestService.delete(processTechnologyId);
        List<ProcessSpecification> byTechnologyId = processSpecificationDao.findByTechnologyId(processTechnologyId);
        if (byTechnologyId != null && byTechnologyId.size() > 0) {
            processSpecificationDao.deleteInBatch(byTechnologyId);
        } else {
            throw new BusinessException("500", "不存在该生产信息");
        }
    }

    /**
     * 导出模板
     *
     * @param response
     */
    public void efforts(HttpServletResponse response) {
        response.setHeader("content-type", "application/octet-stream");
        response.setContentType("application/octet-stream");
        // 下载文件能正常显示中文
        try {
            response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode("工艺工序.xls", "UTF-8"));
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        //创建excel文件夹
        // 创建HSSFWorkbook对象(excel的文档对象)
        HSSFWorkbook wb = new HSSFWorkbook();
        // 建立新的sheet对象（excel的表单）
        HSSFSheet sheet = wb.createSheet("物料管理表");
        // 在sheet里创建第一行，参数为行索引excel的行()
        HSSFRow row1 = sheet.createRow(0);
        // 创建单元格（excel的单元格，参数为列索引，可以是0～255之间的任何一个
        HSSFCell cell = row1.createCell(0);
        // 设置单元格内容
        cell.setCellValue("物料类型*");
        HSSFCell cell1 = row1.createCell(1);
        cell1.setCellValue("物料名称*");
        HSSFCell cell2 = row1.createCell(2);
        cell2.setCellValue("工艺名称*");
        HSSFCell cell3 = row1.createCell(3);
        cell3.setCellValue("批准文号*");
        HSSFCell cell4 = row1.createCell(4);
        cell4.setCellValue("执行标准*");
        HSSFCell cell5 = row1.createCell(5);
        cell5.setCellValue("标准（图片）");
        HSSFCell cell6 = row1.createCell(6);
        cell6.setCellValue("工艺描述1");
        HSSFCell cell7 = row1.createCell(7);
        cell7.setCellValue("工艺描述2");
        HSSFCell cell8 = row1.createCell(8);
        cell8.setCellValue("工艺描述3");
        HSSFCell cell9 = row1.createCell(9);
        cell9.setCellValue("工艺描述4");
        HSSFCell cell10 = row1.createCell(10);
        cell10.setCellValue("工艺描述5");
        HSSFCell cell11 = row1.createCell(11);
        cell11.setCellValue("工艺描述6");
        HSSFCell cell12 = row1.createCell(12);
        cell12.setCellValue("工艺描述7");

        String[] strings = new String[]{"原料", "辅料", "成品", "半成品"};

        DataValidationHelper helper = sheet.getDataValidationHelper();
        DataValidationConstraint constraint = helper.createExplicitListConstraint(strings);
        //设置下拉控制的范围
        CellRangeAddressList regions = new CellRangeAddressList(1, 1024, 0, 0);
        // 绑定下拉框和作用区域
        DataValidation data_validation = helper.createValidation(constraint, regions);
        sheet.addValidationData(data_validation);
        try {
            wb.write(response.getOutputStream());
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * 导入工艺工序
     *
     * @param file
     * @param userId
     * @param companyId
     */
    public void imports(MultipartFile file, String userId, String companyId) {
        //获取文件上传名字
        String originalFilename = file.getOriginalFilename();
        //获取文件流
        InputStream inputStream = null;
        try {
            inputStream = file.getInputStream();
        } catch (IOException e) {
            e.printStackTrace();
        }
        // 判断文件是否是Excel(2003、2007)
        String suffix = originalFilename
                .substring(originalFilename.lastIndexOf("."), originalFilename.length());
        excle(suffix, inputStream, userId, companyId);
    }

    /**
     * 导入数据库
     *
     * @param suffix
     * @param inputStream
     * @param userId
     * @param companyId
     */
    @Transactional
    public void excle(String suffix, InputStream inputStream, String userId, String companyId) {
        // Excel2003
        if (".xls".equals(suffix)) {
            POIFSFileSystem fileSystem = null;
            // 工作簿
            HSSFWorkbook workBook = null;
            try {
                fileSystem = new POIFSFileSystem(inputStream);
                workBook = new HSSFWorkbook(fileSystem);
            } catch (IOException e) {
                e.printStackTrace();
            }
            // 获取第一个工作簿
            HSSFSheet sheet = workBook.getSheetAt(0);
            //获取图片
            Map<String, HSSFPictureData> pictures = null;
            try {
                pictures = getPictures(sheet);
            } catch (IOException e) {
                e.printStackTrace();
            }
            //获取行数
            int rows = sheet.getLastRowNum();

            List<ProcessTechnologys> technologies = null;
            List<ProcessSpecification> specifications = null;
            for (int i = 1; i <= rows; i++) {
                //获取列数
                int clos = sheet.getRow(i).getPhysicalNumberOfCells();
                for (int j = 0; j <= clos; j++) {//获取单元格中内容
                    String materialCode = sheet.getRow(i).getCell(j++).getStringCellValue();
                    String materialName = sheet.getRow(i).getCell(j++).getStringCellValue();
                    List<MaterialManagement> byMaterialName = materialManagementDao.findByMaterialName(materialName);
                    if (byMaterialName.size() == 1) {
                        String materialId = byMaterialName.get(0).getId();
                    } else {
                        throw new BusinessException("数据异常");
                    }
                    String approvalNumber = sheet.getRow(i).getCell(j++).getStringCellValue();
                    String standard = sheet.getRow(i).getCell(j++).getStringCellValue();
                    j++;    //图片名称
                    // String
                }
            }
            // Excel2007
        } else if (".xlsx".equals(suffix)) {
            XSSFWorkbook workBook = null;
            try {
                workBook = new XSSFWorkbook(inputStream);
            } catch (IOException e) {
                e.printStackTrace();
            }
            // 获取第一个工作簿
            XSSFSheet sheet = workBook.getSheetAt(0);
            //获取行数
            int rows = sheet.getLastRowNum();
            //获取列数
            int clos = sheet.getRow(0).getPhysicalNumberOfCells();
            for (int i = 1; i <= rows; i++) {
                MaterialManagement management = new MaterialManagement();
                for (int j = 0; j <= clos; j++) {//获取单元格中内容
                    String materialType = sheet.getRow(i).getCell(j++).getStringCellValue();
                    String materialName = sheet.getRow(i).getCell(j++).getStringCellValue();
                    String materialCode = sheet.getRow(i).getCell(j++).getStringCellValue();
                    String materialSpecification = sheet.getRow(i).getCell(j++).getStringCellValue();
                }

            }
        }
    }

    /**
     * 获取图片
     *
     * @param sheet
     * @return
     * @throws IOException
     */
    public static Map<String, HSSFPictureData> getPictures(HSSFSheet sheet) throws IOException {
        Map<String, HSSFPictureData> map = new HashMap<String, HSSFPictureData>();
        List<HSSFShape> list = sheet.getDrawingPatriarch().getChildren();
        for (HSSFShape shape : list) {
            if (shape instanceof HSSFPicture) {
                HSSFPicture picture = (HSSFPicture) shape;
                HSSFClientAnchor cAnchor = picture.getClientAnchor();
                HSSFPictureData pdata = picture.getPictureData();
                String key = cAnchor.getRow1() + "-" + cAnchor.getCol1();  // 行号-列号
                map.put(key, pdata);
            }
        }
        return map;
    }
}

